package com.gexiaobao.pigeon.app.util

import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.OSS
import com.alibaba.sdk.android.oss.ServiceException
import com.alibaba.sdk.android.oss.model.CompleteMultipartUploadRequest
import com.alibaba.sdk.android.oss.model.InitiateMultipartUploadRequest
import com.alibaba.sdk.android.oss.model.PartETag
import com.alibaba.sdk.android.oss.model.UploadPartRequest
import java.io.File
import java.io.FileInputStream

object MultipartUploader {

    fun uploadLargeFile(
        ossClient: OSS,
        bucketName: String,
        objectKey: String,
        filePath: String,
        partSize: Long = 5 * 1024 * 1024L, // 每个分片大小（5 MB）
        callback: (Boolean, String?) -> Unit
    ) {
        Thread {
            try {
                val file = File(filePath)
                val fileLength = file.length()

                // 1. 初始化分片上传
                val initRequest = InitiateMultipartUploadRequest(bucketName, objectKey)
                val initResult = ossClient.initMultipartUpload(initRequest)
                val uploadId = initResult.uploadId

                // 2. 上传每个分片
                val partETags = mutableListOf<PartETag>()
                val inputStream = FileInputStream(file)
                var currentOffset = 0L
                var partNumber = 1

                while (currentOffset < fileLength) {
                    val partSizeToRead = if (fileLength - currentOffset < partSize) {
                        fileLength - currentOffset
                    } else {
                        partSize
                    }

                    val partBuffer = ByteArray(partSizeToRead.toInt())
                    inputStream.read(partBuffer)

                    val uploadPartRequest = UploadPartRequest(bucketName, objectKey, uploadId, partNumber)
                    uploadPartRequest.partContent = partBuffer
                    val uploadPartResult = ossClient.uploadPart(uploadPartRequest)
                    val partETag = PartETag(uploadPartRequest.partNumber, uploadPartResult.eTag)
                    // 获取 PartETag 并添加到列表
                    partETags.add(partETag)

                    currentOffset += partSizeToRead
                    partNumber++
                }
                inputStream.close()

                // 3. 完成分片上传
                val completeRequest = CompleteMultipartUploadRequest(bucketName, objectKey, uploadId, partETags)
                val completeResult = ossClient.completeMultipartUpload(completeRequest)

                callback(true, completeResult.eTag) // 上传成功
            } catch (ce: ClientException) {
                // 客户端异常（如网络问题）
                callback(false, ce.message)
            } catch (se: ServiceException) {
                // 服务端异常
                callback(false, se.rawMessage)
            }
        }.start()
    }
}
